home *** CD-ROM | disk | FTP | other *** search
/ Network PC / Network PC.iso / amiga utilities / communication / bbs / termv4.6 / extras / source / term-source.lha / CaptureParser.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-03-18  |  10.3 KB  |  524 lines

  1. /*
  2. **    CaptureParser.c
  3. **
  4. **    Capture filter parser
  5. **
  6. **    Copyright © 1990-1996 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. **
  9. **    :ts=4
  10. */
  11.  
  12. #ifndef _GLOBAL_H
  13. #include "Global.h"
  14. #endif
  15.  
  16.  
  17. /**********************************************************************/
  18.  
  19.  
  20. typedef BOOL (* SPECIAL_JUMP)(ParseContext *Context);
  21. typedef BOOL (* ABORT_JUMP)(ParseContext *Context,LONG Char);
  22.  
  23. STATIC SPECIAL_JUMP    *LocalSpecialTable;
  24. STATIC ABORT_JUMP    *LocalAbortTable;
  25.  
  26.  
  27. /**********************************************************************/
  28.  
  29.  
  30. STATIC BOOL
  31. AbortCancel(ParseContext *Context,LONG c)
  32. {
  33.     Context->pc_InSequence        = FALSE;
  34.     Context->pc_CharsInBuffer    = 0;
  35.     Context->pc_ScanStep        = 0;
  36.  
  37.     return(FALSE);
  38. }
  39.  
  40. STATIC BOOL
  41. AbortEsc(ParseContext *Context,LONG c)
  42. {
  43.     AbortCancel(Context,c);
  44.  
  45.     Context->pc_InSequence = TRUE;
  46.  
  47.     return(TRUE);
  48. }
  49.  
  50. STATIC BOOL
  51. LocalParse(ParseContext *Context,LONG c)
  52. {
  53.     if(!Context->pc_ScanStep)
  54.     {
  55.         LONG i;
  56.  
  57.         for(i = 0 ; i < NumCodes ; i++)
  58.         {
  59.             if(ANSICode[i].FirstChar == c)
  60.             {
  61.                 if(ANSICode[i].ExactSize == 1)
  62.                 {
  63.                     Context->pc_CharsInBuffer = Context->pc_ScanStep = 0;
  64.  
  65.                     return(FALSE);
  66.                 }
  67.                 else
  68.                 {
  69.                     Context->pc_ScanStep = i;
  70.  
  71.                     Context->pc_SaveBuffer[Context->pc_CharsInBuffer++] = c;
  72.  
  73.                     Context->pc_Arnie = ANSICode[i].Terminator;
  74.  
  75.                     return(TRUE);
  76.                 }
  77.             }
  78.         }
  79.     }
  80.     else
  81.     {
  82.         if(Context->pc_CharsInBuffer < MAX_SCAN_SIZE)
  83.         {
  84.             if(Context->pc_Arnie)
  85.             {
  86.                 LONG i;
  87.  
  88.                 for(i = Context->pc_ScanStep ; i < NumCodes ; i++)
  89.                 {
  90.                     if(ANSICode[i].FirstChar == Context->pc_SaveBuffer[0])
  91.                     {
  92.                         if(Context->pc_Arnie[c])
  93.                         {
  94.                             Context->pc_CharsInBuffer = Context->pc_ScanStep = 0;
  95.  
  96.                             Context->pc_Arnie = NULL;
  97.  
  98.                             return(FALSE);
  99.                         }
  100.                         else
  101.                         {
  102.                             if(ANSICode[i].Match[c])
  103.                             {
  104.                                 Context->pc_ScanStep = i;
  105.  
  106.                                 Context->pc_SaveBuffer[Context->pc_CharsInBuffer++] = c;
  107.  
  108.                                 return(TRUE);
  109.                             }
  110.                         }
  111.                     }
  112.                 }
  113.             }
  114.             else
  115.             {
  116.                 LONG i;
  117.  
  118.                 for(i = Context->pc_ScanStep ; i < NumCodes ; i++)
  119.                 {
  120.                     if(ANSICode[i].FirstChar == Context->pc_SaveBuffer[0])
  121.                     {
  122.                         if(ANSICode[i].LastChar == c || (!ANSICode[i].LastChar && Context->pc_CharsInBuffer == 2 && ANSICode[i].ExactSize == 3))    // Special case for VT52
  123.                         {
  124.                             Context->pc_CharsInBuffer = Context->pc_ScanStep = 0;
  125.  
  126.                             return(FALSE);
  127.                         }
  128.                         else
  129.                         {
  130.                             if(ANSICode[i].Match[c])
  131.                             {
  132.                                 Context->pc_ScanStep = i;
  133.  
  134.                                 Context->pc_SaveBuffer[Context->pc_CharsInBuffer++] = c;
  135.  
  136.                                 return(TRUE);
  137.                             }
  138.                         }
  139.                     }
  140.                 }
  141.             }
  142.         }
  143.     }
  144.  
  145.     Context->pc_CharsInBuffer = Context->pc_ScanStep = 0;
  146.  
  147.     Context->pc_Arnie = NULL;
  148.  
  149.     return(FALSE);
  150. }
  151.  
  152. STATIC BOOL
  153. AbortCSI(ParseContext *Context,LONG c)
  154. {
  155.     AbortCancel(Context,c);
  156.  
  157.     Context->pc_InSequence = TRUE;
  158.  
  159.     return(LocalParse(Context,'['));
  160. }
  161.  
  162.  
  163. /**********************************************************************/
  164.  
  165.  
  166. STATIC BOOL
  167. SpecialBackspace(ParseContext *Context)
  168. {
  169.     if(Context->pc_LineIndex)
  170.         Context->pc_LineIndex--;
  171.  
  172.     return(FALSE);
  173. }
  174.  
  175. STATIC BOOL
  176. SpecialReturn(ParseContext *Context)
  177. {
  178.     Context->pc_LineIndex = 0;
  179.  
  180.     return(FALSE);
  181. }
  182.  
  183. STATIC BOOL
  184. SpecialTab(ParseContext *Context)
  185. {
  186.     LONG Index = (Context->pc_LineIndex + 7) & ~8;
  187.  
  188.     if(Index > Context->pc_LineLen)
  189.         memset(&Context->pc_LineBuffer[Context->pc_LineLen],' ',Index - Context->pc_LineLen);
  190.  
  191.     Context->pc_LineIndex = Index;
  192.  
  193.     if(Index > Context->pc_LineLen)
  194.         Context->pc_LineLen = Index;
  195.  
  196.     return(FALSE);
  197. }
  198.  
  199. STATIC BOOL
  200. SpecialEsc(ParseContext *Context)
  201. {
  202.     return(TRUE);
  203. }
  204.  
  205. STATIC BOOL
  206. SpecialCSI(ParseContext *Context)
  207. {
  208.     return(LocalParse(Context,'['));
  209. }
  210.  
  211.  
  212. /**********************************************************************/
  213.  
  214.  
  215. VOID
  216. CaptureParserExit()
  217. {
  218.     FreeVecPooled(LocalSpecialTable);
  219.     FreeVecPooled(LocalAbortTable);
  220.  
  221.     LocalSpecialTable = NULL;
  222.     LocalAbortTable = NULL;
  223. }
  224.  
  225. BOOL
  226. CaptureParserInit()
  227. {
  228.     if(LocalSpecialTable = (SPECIAL_JUMP *)AllocVecPooled(256 * sizeof(SPECIAL_JUMP),MEMF_ANY | MEMF_CLEAR))
  229.     {
  230.         if(LocalAbortTable = (ABORT_JUMP *)AllocVecPooled(256 * sizeof(ABORT_JUMP),MEMF_ANY | MEMF_CLEAR))
  231.         {
  232.             STATIC struct { UBYTE Key; SPECIAL_JUMP Routine; } SpecialKeys[] =
  233.             {
  234.                 '\b',    SpecialBackspace,
  235.                 '\r',    SpecialReturn,
  236.                 '\t',    SpecialTab,
  237.                 27,        SpecialEsc,
  238.                 155,    SpecialCSI
  239.             };
  240.  
  241.             LONG i;
  242.  
  243.             for(i = 0 ; i < NumElements(SpecialKeys) ; i++)
  244.                 LocalSpecialTable[SpecialKeys[i].Key] = SpecialKeys[i].Routine;
  245.  
  246.             for(i = 0 ; i < 256 ; i++)
  247.             {
  248.                 switch(AbortMap[i])
  249.                 {
  250.                     case 0:
  251.                         LocalAbortTable[i] = LocalParse;
  252.                         break;
  253.  
  254.                     case 1:
  255.                         LocalAbortTable[i] = AbortCancel;
  256.                         break;
  257.  
  258.                     case 2:
  259.                         LocalAbortTable[i] = AbortEsc;
  260.                         break;
  261.  
  262.                     case 3:
  263.                         LocalAbortTable[i] = AbortCSI;
  264.                         break;
  265.                 }
  266.             }
  267.  
  268.             return(TRUE);
  269.         }
  270.     }
  271.  
  272.     return(FALSE);
  273. }
  274.  
  275. VOID
  276. DeleteParseContext(ParseContext *Context)
  277. {
  278.     FreeVecPooled(Context);
  279. }
  280.  
  281. ParseContext *
  282. CreateParseContext()
  283. {
  284.     return((ParseContext *)AllocVecPooled(sizeof(ParseContext),MEMF_ANY | MEMF_CLEAR));
  285. }
  286.  
  287.  
  288. /**********************************************************************/
  289.  
  290.  
  291.     /* CaptureParser(ParseContext *Context,STRPTR Buffer,LONG Size,COPTR OutputRoutine):
  292.      *
  293.      *    This is very similar to what happens in Emulation.c, in fact we're using the
  294.      *    same data. The basic difference is that no emulation routines are invoked.
  295.      *    Every single one is skipped, only the special control codes like form feed,
  296.      *    tab or carriage return survive. Eventually, we end up building single text
  297.      *    lines that are handed over to the supplied output callback routine. Are we
  298.      *    having fun?
  299.      */
  300.  
  301. VOID
  302. CaptureParser(ParseContext *Context,STRPTR Buffer,LONG Size,COPTR OutputRoutine)
  303. {
  304.     if(Size > 0)
  305.     {
  306.         LONG c;
  307.  
  308.         if(Config->SerialConfig->StripBit8)
  309.         {
  310.             if(Context->pc_InSequence)
  311.             {
  312.                 BOOL Result;
  313.  
  314.                 do
  315.                 {
  316.                     c = *Buffer++ & 0x7F;
  317.  
  318.                     Result = (*LocalAbortTable[c])(Context,c);
  319.                 }
  320.                 while(--Size > 0 && Result);
  321.  
  322.                 Context->pc_InSequence = Result;
  323.             }
  324.  
  325.             if(Size > 0)
  326.             {
  327.                 LONG BufferWidth = Config->CaptureConfig->BufferWidth - 1;
  328.  
  329.                 if(Config->TerminalConfig->FontMode == FONT_STANDARD)
  330.                 {
  331.                     do
  332.                     {
  333.                         c = (*Buffer++) & 0x7F;
  334.  
  335.                         if(Context->pc_InSequence)
  336.                             Context->pc_InSequence = (*LocalAbortTable[c])(Context,c);
  337.                         else
  338.                         {
  339.                             if(LocalSpecialTable[c])
  340.                                 Context->pc_InSequence = (*LocalSpecialTable[c])(Context);
  341.                             else
  342.                             {
  343.                                 if(c == '\n' || c == '\f' || c == '\v')
  344.                                 {
  345.                                     (*OutputRoutine)(Context->pc_LineBuffer,Context->pc_LineLen);
  346.  
  347.                                     Context->pc_LineIndex = Context->pc_LineLen = 0;
  348.                                 }
  349.                                 else
  350.                                 {
  351.                                     if(IsGlyph[c])
  352.                                     {
  353.                                         Context->pc_LineBuffer[Context->pc_LineIndex++] = c;
  354.  
  355.                                         if(Context->pc_LineIndex > Context->pc_LineLen)
  356.                                             Context->pc_LineLen = Context->pc_LineIndex;
  357.  
  358.                                         if(Context->pc_LineLen > BufferWidth)
  359.                                         {
  360.                                             (*OutputRoutine)(Context->pc_LineBuffer,Context->pc_LineLen);
  361.  
  362.                                             Context->pc_LineIndex = Context->pc_LineLen = 0;
  363.                                         }
  364.                                     }
  365.                                 }
  366.                             }
  367.                         }
  368.                     }
  369.                     while(--Size > 0);
  370.                 }
  371.                 else
  372.                 {
  373.                     do
  374.                     {
  375.                         c = (*Buffer++) & 0x7F;
  376.  
  377.                         if(Context->pc_InSequence)
  378.                             Context->pc_InSequence = (*LocalAbortTable[c])(Context,c);
  379.                         else
  380.                         {
  381.                             if(LocalSpecialTable[c])
  382.                                 Context->pc_InSequence = (*LocalSpecialTable[c])(Context);
  383.                             else
  384.                             {
  385.                                 if(c == '\n' || c == '\f' || c == '\v')
  386.                                 {
  387.                                     (*OutputRoutine)(Context->pc_LineBuffer,Context->pc_LineLen);
  388.  
  389.                                     Context->pc_LineIndex = Context->pc_LineLen = 0;
  390.                                 }
  391.                                 else
  392.                                 {
  393.                                     if(c)
  394.                                     {
  395.                                         Context->pc_LineBuffer[Context->pc_LineIndex++] = c;
  396.  
  397.                                         if(Context->pc_LineIndex > Context->pc_LineLen)
  398.                                             Context->pc_LineLen = Context->pc_LineIndex;
  399.  
  400.                                         if(Context->pc_LineLen > BufferWidth)
  401.                                         {
  402.                                             (*OutputRoutine)(Context->pc_LineBuffer,Context->pc_LineLen);
  403.  
  404.                                             Context->pc_LineIndex = Context->pc_LineLen = 0;
  405.                                         }
  406.                                     }
  407.                                 }
  408.                             }
  409.                         }
  410.                     }
  411.                     while(--Size > 0);
  412.                 }
  413.             }
  414.         }
  415.         else
  416.         {
  417.             if(Context->pc_InSequence)
  418.             {
  419.                 BOOL Result;
  420.  
  421.                 do
  422.                 {
  423.                     c = *Buffer++;
  424.  
  425.                     Result = (*LocalAbortTable[c])(Context,c);
  426.                 }
  427.                 while(--Size > 0 && Result);
  428.  
  429.                 Context->pc_InSequence = Result;
  430.             }
  431.  
  432.             if(Size > 0)
  433.             {
  434.                 LONG BufferWidth = Config->CaptureConfig->BufferWidth - 1;
  435.  
  436.                 if(Config->TerminalConfig->FontMode == FONT_STANDARD)
  437.                 {
  438.                     do
  439.                     {
  440.                         c = *Buffer++;
  441.  
  442.                         if(Context->pc_InSequence)
  443.                             Context->pc_InSequence = (*LocalAbortTable[c])(Context,c);
  444.                         else
  445.                         {
  446.                             if(LocalSpecialTable[c])
  447.                                 Context->pc_InSequence = (*LocalSpecialTable[c])(Context);
  448.                             else
  449.                             {
  450.                                 if(c == '\n' || c == '\f' || c == '\v')
  451.                                 {
  452.                                     (*OutputRoutine)(Context->pc_LineBuffer,Context->pc_LineLen);
  453.  
  454.                                     Context->pc_LineIndex = Context->pc_LineLen = 0;
  455.                                 }
  456.                                 else
  457.                                 {
  458.                                     if(IsGlyph[c])
  459.                                     {
  460.                                         Context->pc_LineBuffer[Context->pc_LineIndex++] = c;
  461.  
  462.                                         if(Context->pc_LineIndex > Context->pc_LineLen)
  463.                                             Context->pc_LineLen = Context->pc_LineIndex;
  464.  
  465.                                         if(Context->pc_LineLen > BufferWidth)
  466.                                         {
  467.                                             (*OutputRoutine)(Context->pc_LineBuffer,Context->pc_LineLen);
  468.  
  469.                                             Context->pc_LineIndex = Context->pc_LineLen = 0;
  470.                                         }
  471.                                     }
  472.                                 }
  473.                             }
  474.                         }
  475.                     }
  476.                     while(--Size > 0);
  477.                 }
  478.                 else
  479.                 {
  480.                     do
  481.                     {
  482.                         c = *Buffer++;
  483.  
  484.                         if(Context->pc_InSequence)
  485.                             Context->pc_InSequence = (*LocalAbortTable[c])(Context,c);
  486.                         else
  487.                         {
  488.                             if(LocalSpecialTable[c])
  489.                                 Context->pc_InSequence = (*LocalSpecialTable[c])(Context);
  490.                             else
  491.                             {
  492.                                 if(c == '\n' || c == '\f' || c == '\v')
  493.                                 {
  494.                                     (*OutputRoutine)(Context->pc_LineBuffer,Context->pc_LineLen);
  495.  
  496.                                     Context->pc_LineIndex = Context->pc_LineLen = 0;
  497.                                 }
  498.                                 else
  499.                                 {
  500.                                     if(c)
  501.                                     {
  502.                                         Context->pc_LineBuffer[Context->pc_LineIndex++] = c;
  503.  
  504.                                         if(Context->pc_LineIndex > Context->pc_LineLen)
  505.                                             Context->pc_LineLen = Context->pc_LineIndex;
  506.  
  507.                                         if(Context->pc_LineLen > BufferWidth)
  508.                                         {
  509.                                             (*OutputRoutine)(Context->pc_LineBuffer,Context->pc_LineLen);
  510.  
  511.                                             Context->pc_LineIndex = Context->pc_LineLen = 0;
  512.                                         }
  513.                                     }
  514.                                 }
  515.                             }
  516.                         }
  517.                     }
  518.                     while(--Size > 0);
  519.                 }
  520.             }
  521.         }
  522.     }
  523. }
  524.